package streamobject

import (
	"bytes"
	"github.com/pkg/errors"
	"yizhuoyan/go-study/pdfgo/handyio"
	"yizhuoyan/go-study/pdfgo/raw/filters"
	"yizhuoyan/go-study/pdfgo/raw/objects/basicobject"
)

type BytesStreamObject struct {
	dic          *basicobject.Dictionary
	filter       []string
	DecodeParms  *basicobject.DictionaryOrArray
	F            any
	FFilter      []string
	FDecodeParms *basicobject.DictionaryOrArray
	DL           uint64
	bytes        []byte
}

func (this *BytesStreamObject) GetType() string {
	return "/BytesStream"
}

func (this *BytesStreamObject) Serialize(w handyio.PdfRawWriter) error {
	if err := this.dic.Serialize(w); err != nil {
		return err
	}
	w.WriteEndOfLine()
	w.WriteBytes(StartStreamKeywordBytes)
	w.WriteBytes(this.bytes)
	w.WriteEndOfLine()
	w.WriteBytes(EndStreamKeywordBytes)
	return nil
}
func (this *BytesStreamObject) GetFilters() []string {
	if this.filter != nil {
		return this.filter
	}
	rst := this.dic.Get("/Filter")
	if rst == nil {
		this.filter = []string{}
		return this.filter
	}
	if arr, is := rst.(*basicobject.Array); is {
		this.filter = arr.MustToStringArray()
		return this.filter
	} else if name, is := rst.(*basicobject.Name); is {
		this.filter = []string{name.GetNameValue()}
		return this.filter
	}
	panic(errors.Errorf("无法识别Filter"))
}
func (this *BytesStreamObject) Length() int {

	return this.dic.MustGetInteger("/Length").ValueInt()
}
func (this *BytesStreamObject) UnSerialize(r handyio.PdfRawReader) error {
	var dic = new(basicobject.Dictionary)
	if err := dic.UnSerialize(r); err != nil {
		return errors.Wrapf(err, "UnSerialize BytesStreamObject")
	}
	return this.ReadStream(dic, r)
}
func (this *BytesStreamObject) ReadStream(dic *basicobject.Dictionary, r handyio.PdfRawReader) error {

	startAt := r.IndexCurrent()
	if !r.NextBytesEquals(StartStreamKeywordBytes) {
		return r.NotSupport("无stream开头")
	}
	this.dic = dic
	length := this.Length()
	r.SkipNextEndOfLine()
	var buf = new(bytes.Buffer)
	for i := 0; i < length; i++ {
		nextByte, err := r.NextByte()
		if err != nil {
			_ = r.IndexMoveTo(startAt)
			return err
		}
		buf.WriteByte(nextByte)
	}
	this.bytes = buf.Bytes()
	r.SkipNextEndOfLine()
	if !r.NextBytesEquals(EndStreamKeywordBytes) {
		_ = r.IndexMoveTo(startAt)
		return r.NotSupport("无endstream")
	}
	//解码
	filterArray := this.GetFilters()
	if len(filterArray) > 0 {
		var err error
		this.bytes, err = filters.NewCompositeFilter(filterArray).Decode(this.bytes)
		if err != nil {
			return errors.Wrapf(err, "解码")
		}
	}
	return nil
}
func (this *BytesStreamObject) GetDictionary() *basicobject.Dictionary {
	return this.dic
}
